//+---------------------------------------------------------------------------
//
// Copyright (C) Microsoft Corporation, 2008
//
// File: XmlFileParser.cs
//
// Contents: Generic XmlStringParser (Serializer/Deserializer)
//
// Created by: AdamWa 2008 Mar 18
//
//----------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace Microsoft.Reputation.Services
{
    public static class XmlParser
    {
        private static XmlWriterSettings s_xmlWriterSettings = CreateXmlWriterSettings();

        private static XmlWriterSettings CreateXmlWriterSettings()
        {
            XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
            xmlWriterSettings.Indent = false;
            xmlWriterSettings.OmitXmlDeclaration = true;
            xmlWriterSettings.NewLineChars = string.Empty;
            return xmlWriterSettings;
        }

        public static string ToXmlString<T>(T theObject)
        {
            TraceUtility.TraceAssert(Tracing.Source, theObject != null);

            using (TraceUtility.TraceMethod(Tracing.Source))
            {
                try
                {
                    StringBuilder sb = new StringBuilder();
                    using (XmlWriter xmlWriter = XmlWriter.Create(sb, s_xmlWriterSettings))
                    {
                        XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
                        xmlSerializer.Serialize(xmlWriter, theObject);
                    }
                    return sb.ToString();
                }
                catch (InvalidOperationException ex)
                {
                    TraceUtility.TraceCatchException(Tracing.Source, ex);

                    BaseException baseEx = new BaseException(ex, new BaseExceptionContext(
                        string.Format(
                            CultureInfo.InvariantCulture,
                            "{0} {1}",
                            ex.Message,
                            ex.InnerException.Message),
                        CommonStrings.ErrorMessage_XmlFileParser_CouldNotSerializeObject,
                        typeof(T).ToString()));
                    TraceUtility.TraceThrowException(Tracing.Source, baseEx);
                    throw baseEx;
                }
            }
        }

        public static T FromXmlReader<T>(XmlReader xmlReader)
        {
            TraceUtility.TraceAssert(Tracing.Source, xmlReader != null);

            using (TraceUtility.TraceMethod(Tracing.Source))
            {
                try
                {
                    XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
                    return (T)xmlSerializer.Deserialize(xmlReader);
                }
                catch (InvalidOperationException ex)
                {
                    TraceUtility.TraceCatchException(Tracing.Source, ex);

                    BaseException baseEx = new BaseException(ex, new BaseExceptionContext(
                        string.Format(
                            CultureInfo.InvariantCulture,
                            "{0} {1}",
                            ex.Message,
                            ex.InnerException.Message),
                        CommonStrings.ErrorMessage_XmlFileParser_CouldNotDeserializeObject,
                        typeof(T).ToString()));
                    TraceUtility.TraceThrowException(Tracing.Source, baseEx);
                    throw baseEx;
                }
            }
        }

        public static T FromXmlString<T>(string xmlString)
        {
            TraceUtility.TraceAssert(Tracing.Source, xmlString != null);
            
            using (TraceUtility.TraceMethod(Tracing.Source))
            {
                try
                {
                    using (StringReader stringReader = new StringReader(xmlString))
                    {
                        XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
                        return (T)xmlSerializer.Deserialize(stringReader);
                    }
                }
                catch (InvalidOperationException ex)
                {
                    TraceUtility.TraceCatchException(Tracing.Source, ex);

                    BaseException baseEx = new BaseException(ex, new BaseExceptionContext(
                        string.Format(
                            CultureInfo.InvariantCulture,
                            "{0} {1}",
                            ex.Message,
                            ex.InnerException.Message),
                        CommonStrings.ErrorMessage_XmlFileParser_CouldNotDeserializeObject,
                        typeof(T).ToString()));
                    TraceUtility.TraceThrowException(Tracing.Source, baseEx);
                    throw baseEx;
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="o"></param>
        /// <returns></returns>
        public static string ToXml<T>(T o)
        {
            return XmlParser.ToXmlString<T>(o).Replace(
                " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"",
                string.Empty);
        }
    }
}
